#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <mosquitto.h>
#include <sys/time.h>
// #include <time.h>
#include <sys/sysinfo.h>
#include <errno.h>
#include "queue.h"
#include "cJSON.h"
#include "mqtt_cli.h"
#include "log.h"
#include "action_func.h"
#include "fast_conble_func.h"
#include "json_data.h"

/*全局变量区*/
struct mosquitto *g_test_mosq = NULL;

// 查询网关类信号量
sem_t reportDevState_limitSem; // 查询设备状态的信号量，为1，处理多个设备上报请求冲突
// 网关接收到查询类消息时放入消息队列
sem_t reportDevState_syncSem; // 查询设备状态的信号量，为0，同步查询结果
bool reportDevState_syncSem_initialized = false;

// 设备、场景、群组控制类信号量，同步回复
sem_t controlResult_Sem; // 发出控制指令为1，收到回复为0
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

struct msg_buffer message_recv;
key_t msg_key;
int msgid;

// Define categories
const char *g_all_action[MQTT_TOPIC_NUMBER] = {
    "hz.list.project",
    "hz.list.space",
    "hz.list.region",
    "hz.list.group",
    "hz.list.scene",
    "hz.list.device",

    "hz.detail.project",
    "hz.detail.space",
    "hz.detail.region",
    "hz.detail.group",
    "hz.detail.scene",
    "hz.detail.device",

    "hz.status.project",
    "hz.status.space",
    "hz.status.region",
    "hz.status.group",
    "hz.status.scene",
    "hz.status.device",

    "hz.modify.project",
    "hz.modify.space",
    "hz.modify.region",
    "hz.modify.group",
    "hz.modify.scene",
    "hz.modify.device",

    "hz.control.all",
    "hz.control.project",
    "hz.control.space",
    "hz.control.region",
    "hz.control.group",
    "hz.control.scene",
    "hz.control.device",

    "hz.log.project",
    "hz.log.space",
    "hz.log.region",
    "hz.log.group",
    "hz.log.scene",
    "hz.log.device",

    "hz.energy.all",
    "hz.energy.project",
    "hz.energy.space",
    "hz.energy.region",
    "hz.energy.group",
    "hz.energy.device",

    "hz.event.message",
    "hz.event.alert",
    "hz.event.fault"};

/*内部变量区*/
static char client_id[64] = {0};        // mqtt的client id
static MessageQueue mqtt_message_queue; // 接收的消息队列
static unsigned short send_msg_sequence = 0;
hz_area_t hz_area = {project : "project", space : "space", region : "region", group : "group", scene : "scene", device : "device", all : "all"};
hz_info_t hz_info = {list : "list", detail : "detail", status : "status", modify : "modify", control : "control", log : "log", energy : "energy", event : "event"};

/*宏定义*/
#define RECV_MSG_MAX_LEN 1024

/**
 * @description: 生成json信息
 * @param {unsigned short} seq由客户端生成，返回时相同
 * @param {char*} action请求的接口如hz.list.project
 * @param {bool} status 0,1失败成功
 * @param {char*} msg信息段
 * @param {cJSON} *data_json json内容
 * @return {*}
 */
char *generate_json_msg(unsigned short seq, const char *action, bool status, char *msg, cJSON *data_json)
{
    // 获取当前时间
    time_t rawtime;
    struct tm *timeinfo;

    char seq_str[6] = "";
    char time_str[25] = "";
    char status_str[8] = "";

    sprintf(seq_str, "%d", seq);

    time(&rawtime);
    timeinfo = gmtime(&rawtime); // 使用 gmtime 获取协调世界时（UTC）的时间结构体
    // 格式化时间成字符串
    strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%S.000Z", timeinfo);

    // timeinfo = localtime(&rawtime);  // 使用 localtime 获取本地时间结构体
    // strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%S.000%z", timeinfo);
    //  将时区的冒号分隔符改为无分隔符
    //  for (int i = 22; i < 25; ++i) {
    //      time_str[i] = time_str[i + 1];
    //  }

    if (status)
        memcpy(status_str, "success", 7);
    else
        memcpy(status_str, "failed", 6);

    // 创建 JSON 对象
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "seq", seq_str);
    cJSON_AddStringToObject(root, "time", time_str);
    cJSON_AddStringToObject(root, "action", time_str);
    cJSON_AddStringToObject(root, "status", status_str);
    cJSON_AddStringToObject(root, "msg", msg);
    cJSON_AddItemToObject(root, "data", cJSON_Duplicate(data_json, 1));
    // 应该复制一个，否则下面的释放会影响到上面的值
    char *json_msg = cJSON_PrintUnformatted(root);

    // 使用完释放掉资源
    cJSON_Delete(root);

    // 打印 JSON 字符串
    log_debug("JSON字符串: %s\n", json_msg);
    return json_msg;
}

/**
 * @description: 发送mqtt信息，调用产生json函数，
 * @param {char} *info 主题构成{clientId}/hz/{info}
 * @param {char} *area 主题构成{clientId}/hz/{info}/{area}
 * @param {char} *data json的文本数据
 * @param {int} len json的文本数据的长度
 * @return {*}
 */
int mqtt_send_msg(char *info, char *area, char *data, int len)
{
    char action_api[30] = "";
    char additionalJsonData[] = "{\"key1\":\"value1\",\"key2\":42}";
    cJSON *data_json = cJSON_Parse(additionalJsonData);
    sprintf(action_api, "hz.%s.%s", info, area);                                  // 构建以.分割的主题，正常主题用/分割
    char *msg_payload = generate_json_msg(1234, action_api, true, "", data_json); // json内部用到主题数据
    sprintf(action_api, "hz/%s/%s", info, area);                                  // 构建主题
    printf("%s\n", msg_payload);
    mqtt_bcast_msg(action_api, msg_payload, strlen(msg_payload));
}

int mqtt_send_json(char *info, char *area, bool status, cJSON *data_json)
{
    char action_api[30] = "";
    // char additionalJsonData[] = "{\"key1\":\"value1\",\"key2\":42}";
    // cJSON *data_json = cJSON_Parse(additionalJsonData);

    sprintf(action_api, "hz.%s.%s", info, area);                                    // 构建以.分割的主题，正常主题用/分割
    char *msg_payload = generate_json_msg(1234, action_api, status, "", data_json); // json内部用到主题数据
    sprintf(action_api, "hz/%s/%s", info, area);                                    // 构建主题
    printf("%s\n", msg_payload);
    mqtt_bcast_msg(action_api, msg_payload, strlen(msg_payload));
}

// 动作执行
int action_process(char *action, cJSON *params)
{
    int ret = -1;

    if ((action == NULL) || (params == NULL))
    {
        log_error("action or params is NULL\n");
        return ret;
    }

    // 获取 params 中的 id 的内容
    cJSON *idObject = cJSON_GetObjectItem(params, "id");
    // 获取list列表类时，id为空
    if (idObject == NULL)
    {
        log_error("Error retrieving 'id' from 'params' in JSON.\n");
        return ret;
    }
    log_debug("params.id: %s\n", idObject->valuestring);

    // 获取 params 中的 filter 的内容
    cJSON *filterObject = cJSON_GetObjectItem(params, "filter");
    if (filterObject == NULL || !cJSON_IsArray(filterObject))
    {
        log_error("Error retrieving 'filter' from 'params' in JSON.\n");
        return ret;
    }
    // log_debug("params.filter: %s\n", filterObject->valuestring);

    // 获取 params 中的 config 的内容
    cJSON *configObject = cJSON_GetObjectItem(params, "config");
    if (configObject == NULL || !cJSON_IsArray(configObject))
    {
        log_error("Error retrieving 'config' from 'params' in JSON.\n");
        return ret;
    }
    // log_debug("params.config: %s\n", configObject->valuestring);

    // 根据json第一层对象action的值，确定调用的函数，并传入参数id值（字符串），filter和config对象。
    for (int i = 0; i < MQTT_TOPIC_NUMBER; i++)
    {
        if (strncmp(action, g_all_action[i], strlen(g_all_action[i])) == 0)
        {
            functionPointers[i](idObject->valuestring, filterObject, configObject);
            break;
        }
    }
}

// 消息包处理线程
#define MSG_BUFFER_MAX 64 * 1024 // 64KB
void *msg_process_thread(void *arg)
{
    int ret = 0;
    char *msgPayload = NULL;
    uint8_t receivedFlag = 0; // 接收完成标志
    char *text = NULL;
    cJSON *json = NULL;
    /*初始化队列*/
    MessageQueue *mq = (MessageQueue *)arg;
    initializeMessageQueue(mq);
    log_debug("mqtt_message_queue %p sizeof(MessageQueue) %d\n", mq, sizeof(MessageQueue));

    msgPayload = (char *)calloc(MSG_BUFFER_MAX + 1, 1);
    if (msgPayload == NULL)
    {
        fprintf(stderr, "memory alloc failed\n");
    }
    while (1)
    {
        MessageIndex messIndex = {0};
        uint16_t msgIndex = 0;
        uint16_t msgCount = 0;
        uint16_t JsonType = 0;
        uint32_t messPayloadLen = 0;
        log_debug("wait msg\n");
        Message msg = dequeueMessage(mq);

        // Process the message (in this example, just print it)
        messIndex = *(MessageIndex *)(msg.data + 0);
        msgIndex = messIndex.index;
        msgCount = messIndex.count;
        JsonType = messIndex.type;
        messPayloadLen = messIndex.payloadLen;
        log_debug("queue receive: In:%d, Co:%d, Js:%d", msgIndex, msgCount, JsonType);
        log_debug("Worker Thread: Processing Message: %.*s\n", msg.length, msg.data + 24);
        printf("pack:%.10s\n", (char *)(msg.data + 24));
        if (messPayloadLen > MSG_BUFFER_MAX)
        {
            fprintf(stderr, "queue size too large\n");
        }
        // printf("len:%d\n", msg.length);
        // printf("len:%d\n", msgIndex);
        // printf("len:%d\n", msgCount);
        if (msgCount == 1)
        {
            // msgPayload = (char *)calloc(messPayloadLen + 1, 1); // 保持最后一个字节为0
            // if (msgPayload == NULL)
            // {
            //     fprintf(stderr, "memory alloc failed\n");
            //     continue;
            // }
            memcpy(msgPayload, (char *)(msg.data + 24), msg.length);
            msgPayload[msg.length] = 0; // 结尾
            receivedFlag = 1;           // 接收完成
        }
        else
        {
            log_info("packet No:%d", msgIndex);
            memcpy(msgPayload + (msgIndex - 1) * MAX_MESSAGE_PAYLOAD_LENGTH, (char *)msg.data + 24, msg.length);
            if (msgIndex == 1) // 第一个包
            {
                // msgPayload = (char *)calloc(messPayloadLen, 1);
                // if (msgPayload == NULL)
                // {
                //     fprintf(stderr, "memory alloc failed\n");
                //     continue;
                // }
            }
            else if (msgIndex == msgCount) // 最后一包
            {
                receivedFlag = 1; // 接收完成

                // log_info("packet1:%s", msgPayload);
                msgPayload[(msgIndex - 1) * MAX_MESSAGE_PAYLOAD_LENGTH + msg.length] = 0; // 结尾
                // log_info("packet:%s", msgPayload);
            }
        }

        if (!receivedFlag)
        {
            continue;
        }
        else
        {
            receivedFlag = 0;
            log_info("mqtt接收完成");
            switch (JsonType)
            {
            case 1: // hz/user/get主题
                log_info("mqtt hz/user/get主题");
                text = attributeToSerName(msgPayload); // 后面有释放
                json = cJSON_Parse(text);
                free(text);
                mqttMsg_hz_user_get(json);
                // 释放 cJSON 结构体
                cJSON_Delete(json);
                break;
            case 2: // devices/screen/rhy/info主题
                ret = read_rhythmData(msgPayload);
                log_info("mqtt devices/screen/rhy/info主题, ret:%d", ret);
                break;
            default:
                break;
            }
        }
    }

    return NULL;
}

void mqttMsg_hz_user_get(cJSON *json)
{
    // 解析接收到的json数据包，第一层json对象有seq, time, action, params四个
    //  获取 seq 的内容
    cJSON *seqObject = cJSON_GetObjectItem(json, "seq");
    if (seqObject == NULL)
    {
        fprintf(stderr, "Error retrieving 'seq' from JSON.\n");
        // cJSON_Delete(json);
        return;
    }
    // 打印 seq 的内容
    log_debug("seq: %s\n", seqObject->valuestring);

    // 获取 time 的内容
    cJSON *timeObject = cJSON_GetObjectItem(json, "time");
    if (timeObject == NULL)
    {
        fprintf(stderr, "Error retrieving 'time' from JSON.\n");
        // cJSON_Delete(json);
        return;
    }
    // 打印 time 的内容
    log_debug("time: %s\n", timeObject->valuestring);

    // 获取 action 的内容
    cJSON *actionObject = cJSON_GetObjectItem(json, "action");
    if (actionObject == NULL)
    {
        fprintf(stderr, "Error retrieving 'action' from JSON.\n");
        // cJSON_Delete(json);
        return;
    }
    // 打印 action 的内容
    log_debug("action: %s\n", actionObject->valuestring);

    // 获取嵌套的 params
    cJSON *paramsObject = cJSON_GetObjectItem(json, "params");
    if (paramsObject == NULL)
    {
        fprintf(stderr, "Error retrieving 'params' from JSON.\n");
        // cJSON_Delete(json);
        return;
    }

    jsonValueToSerStr(paramsObject); // 修改json字符值形态以符合服务器要求
    action_process(actionObject->valuestring, paramsObject);
}

void mqttMsg_devices_screen_rhy_info(cJSON *json)
{
}

// 连接回调
void mqtt_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
    char sub_topic[1024] = "";
    int ret = 0;

    log_debug("connect to mqtt server ok\n");

    /*设备端订阅主题*/
    ret = snprintf(sub_topic, sizeof(sub_topic), "%s/hz/user/get", client_id);
    if (ret >= sizeof(sub_topic))
    {
        fprintf(stderr, "sub top buffer error\n");
        return;
    }
    if (MOSQ_ERR_SUCCESS != mosquitto_subscribe(mosq, NULL, sub_topic, 0))
    {
        log_warn("sub topic %s failed...\n", sub_topic);
    }
    else
    {
        log_info("sub topic %s success...\n", sub_topic);
    }

    // 增加订阅主题
    /*设备端订阅主题*/
    memset(sub_topic, 0, sizeof(sub_topic));
    ret = snprintf(sub_topic, sizeof(sub_topic), "%s/devices/screen/rhy/info", client_id);
    if (ret >= sizeof(sub_topic))
    {
        fprintf(stderr, "sub top buffer error\n");
        return;
    }
    if (MOSQ_ERR_SUCCESS != mosquitto_subscribe(mosq, NULL, sub_topic, 0))
    {
        log_warn("sub topic %s failed...\n", sub_topic);
    }
    else
    {
        log_info("sub topic %s success...\n", sub_topic);
    }

    /*启动消息处理线程*/
    // MessageQueue mqtt_message_queue;
    // for (int i = 0; i < MAX_MESSAGE_COUNT; i++)
    // {
    //     // mqtt_message_queue.messages[i].data = (char *)malloc(MAX_MESSAGE_LENGTH);
    //     mqtt_message_queue.messages[i].data = (char *)calloc(MAX_MESSAGE_LENGTH, 1);
    //     if (mqtt_message_queue.messages[i].data == NULL)
    //     {
    //         fprintf(stderr, "calloc error\n");
    //         return;
    //     }
    // }

    pthread_t thread;
    pthread_create(&thread, NULL, msg_process_thread, &mqtt_message_queue);

    // mqtt_send_msg(hz_info.list, hz_area.project, )
}

// 断开连接回调
void mqtt_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)
{
    if (result)
        log_info("disconnect %s\n", mosquitto_connack_string(result));
    else
        log_info("disconnect from mqtt server.\n");

    for (int i = 0; i < MAX_MESSAGE_COUNT; i++)
        free(mqtt_message_queue.messages[i].data);
}

void mqtt_sub_callback(struct mosquitto *mosq,
                       void *userdata,
                       int mid,
                       int qos_count,
                       const int *granted_qos)
{
    log_debug("sub callback\n");
}

void mqtt_msg_callback(struct mosquitto *mosq,
                       void *userdata,
                       const struct mosquitto_message *message)
{
    uint16_t JsonType = 0;
    MessageIndex messIndex = {0};
    // log_debug("callback recv mqtt msg, topic = %s, payload = %s\n", message->topic, message->payload);
    // mqtt_bcast_msg("hz/list/project", message->payload, message->payloadlen);
    // log_debug("callbakc payload Len:%d, %d", message->payloadlen, strlen(message->payload));

    char *topicSub = strchr(message->topic, '/') + 1; // 第一个/后面的字符串
    if (topicSub == NULL)
    {
        log_info("top error: %s", message->topic);
        return;
    }
    else
    {
        if (!strcmp(topicSub, "hz/user/get"))
        {
            JsonType = 1;
        }
        else if (!strcmp(topicSub, "devices/screen/rhy/info"))
        {
            JsonType = 2;
        }
    }
    printf("type:%d, %s\n", JsonType, topicSub);
    // enqueueMessage(&mqtt_message_queue, message->payload, message->payloadlen);
    // 在前面取4字节，前两字节表示分包序号，后两字节表示分包总数。

    if (message->payloadlen <= MAX_MESSAGE_PAYLOAD_LENGTH) // 一个队列装完数据
    {
        messIndex.index = 1;
        messIndex.count = 1;
        messIndex.type = JsonType;
        messIndex.payloadLen = message->payloadlen;
        enqueueMessageIndex(&mqtt_message_queue, message->payload, message->payloadlen, messIndex);
    }
    else // 多个队列装完数据
    {
        int packetCount = message->payloadlen / MAX_MESSAGE_PAYLOAD_LENGTH;   // 分包数
        int packetEndSize = message->payloadlen % MAX_MESSAGE_PAYLOAD_LENGTH; // 最后包大小
        messIndex.count = packetCount;
        messIndex.type = JsonType;
        messIndex.payloadLen = message->payloadlen;
        // printf("lenn:%d\n", messIndex.payloadLen);
        if (packetEndSize > 0)
        {
            packetCount += 1; // 余数大于0要增加一包
            messIndex.count = packetCount;
        }
        else
        {
            packetEndSize = MAX_MESSAGE_PAYLOAD_LENGTH; // 余数为0，则最后一包大小为除数MAX_MESSAGE_PAYLOAD_LENGTH
        }
        for (int i = 0; i < packetCount - 1; i++)
        {
            messIndex.index = i + 1;
            // messIndex.count = i + 1;
            log_debug("queue before:%d", messIndex.index);
            printf("queue:%.10s\n", message->payload + MAX_MESSAGE_PAYLOAD_LENGTH * i);
            enqueueMessageIndex(&mqtt_message_queue, message->payload + MAX_MESSAGE_PAYLOAD_LENGTH * i, MAX_MESSAGE_PAYLOAD_LENGTH, messIndex);
        }
        // 最后一包要另外处理
        messIndex.index = packetCount;
        // messIndex.count = packetCount;
        log_debug("queue last:%d", messIndex.index);
        printf("queue last:%.10s\n", message->payload + MAX_MESSAGE_PAYLOAD_LENGTH * (packetCount - 1));
        enqueueMessageIndex(&mqtt_message_queue, message->payload + MAX_MESSAGE_PAYLOAD_LENGTH * (packetCount - 1), packetEndSize, messIndex);
    }
}
/*发布消息到对应主题*/
// int mqtt_msg_pub_list_project(unsigned char *payload, int len)
// {
//     char pub_topic[64] = "";
//     sprintf(pub_topic, "%s/hz/list/project", client_id);
//     mosquitto_publish(mosq, NULL, pub_topic, message->payloadlen, message->payload, 0, false);
// }

// 连接服务器
struct mosquitto *connect_to_mqtt_server(char *server_ip)
{
#define FSLMQTT 1
    struct mosquitto *mosq = NULL;
    int rc;
    char mqtt_user[128] = {0};
    char mqtt_pwd[128] = {0};

    struct timeval tv;
    gettimeofday(&tv, NULL);
    mosquitto_lib_init();

    memset(client_id, 0, sizeof(client_id));
    memcpy(client_id, "92fcb0dhh6943dcg", sizeof("92fcb0dhh6943dcg"));
    // memcpy(client_id, "mqttx_b8b140f9", sizeof("mqttx_b8b140f9"));
    // snprintf(client_id, sizeof(client_id), "test_%d", tv.tv_sec);
    log_debug("connect to mqtt server..client_id=%s\n", client_id);
    mosq = mosquitto_new(client_id, true, NULL);
    if (!mosq)
    {
        return NULL;
    }

#if FSLMQTT
    memcpy(mqtt_user, "GGSRN4-92fcb0d", sizeof("GGSRN4-92fcb0d"));
    memcpy(mqtt_pwd, "gSXuWf1TXbVlv3Q3", sizeof("gSXuWf1TXbVlv3Q3"));
    mosquitto_username_pw_set(mosq, mqtt_user, mqtt_pwd);
    mosquitto_tls_set(mosq, "./cacert.pem", NULL, NULL, NULL, NULL);
    // mosquitto_tls_set(mosq, "/root/cacert.pem", NULL, NULL, NULL, NULL);
#else
    memcpy(mqtt_user, "user", sizeof(mqtt_user));
    memcpy(mqtt_pwd, "123456", sizeof(mqtt_pwd));
    mosquitto_username_pw_set(mosq, mqtt_user, mqtt_pwd);
#endif
    mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
    mosquitto_message_callback_set(mosq, mqtt_msg_callback);
    mosquitto_subscribe_callback_set(mosq, mqtt_sub_callback);
    mosquitto_disconnect_callback_set(mosq, mqtt_disconnect_callback);
#if FSLMQTT
    rc = mosquitto_connect(mosq, server_ip, 21005, 30);
#else
    rc = mosquitto_connect(mosq, server_ip, 1883, 30);
#endif
    if (rc)
    {
        log_error("Unable to connect mqtt server rc=%d\n", rc);
        mosquitto_destroy(mosq);
        return NULL;
    }

    return mosq;
}

void replaceDotsWithSlashes(char *str)
{
    int len = strlen(str);

    for (int i = 0; i < len; ++i)
    {
        if (str[i] == '.')
        {
            str[i] = '/';
        }
    }
}

/**
 * @description: 发布主题
 * @param {char} *api  /hz/user/get
 * @param {char} *data 发送的数据
 * @param {int} len 数据长度
 * @return {*}发布成功0
 */
int mqtt_bcast_msg(char *api, char *data, int len)
{
    char topic[64] = {0};
    char api_tmp[50] = {0};
    int mid;
    if (!api || !data || len == 0)
        return -1;
    if (!g_test_mosq)
        return -1;

    // 将action中的.替换成/
    memcpy(api_tmp, api, strlen(api));
    for (int i = 0; i < len; ++i)
    {
        if (api_tmp[i] == '.')
        {
            api_tmp[i] = '/';
        }
    }

    sprintf(topic, "%s/%s", client_id, api_tmp);
    printf("topic:%s\n", topic);
    return mosquitto_publish(g_test_mosq, &mid, topic, len, data, 0, 0);
}

void mqtt_publish_test()
{
    mqtt_send_msg(hz_info.list, hz_area.project, "", 0);
    // int mid;
    // char topic[64] = "92fcb0dhh6943dcg/hz/list/project";
    // char data[64] = "{\"key1\":\"value1\",\"key2\":42}";
    // int len;
    // len = strlen(data);
    // mosquitto_publish(g_test_mosq, &mid, topic, len, data, 0, 0);
}

// 多进程通信处理，信号量
void report_sem_init()
{
    sem_init(&reportDevState_limitSem, 0, 1);
    // 同步信号量则在使用时初始化
}

uint8_t report_sem_post()
{
    int ret = 0;
    ret = sem_post(&reportDevState_limitSem); // 释放信号量+1
    return ret;
}

/**
 * @description: 无阻塞获取report信号量
 * @return {*}返回0成功获取信号量-1，返回-1/error EAGAIN信号量不可用（=0），其他值则失败
 */
uint8_t report_sem_trywait()
{
    int ret = 0;
    ret = sem_trywait(&reportDevState_limitSem);
    return ret;
}

void controlResult_Sem_init()
{
    sem_init(&controlResult_Sem, 0, 0); // 信号量初始为0
}
int controlResult_Sem_post()
{
    int ret = 0;
    ret = sem_post(&controlResult_Sem); // 释放信号量+1
    return ret;
}
int controlResult_Sem_timedwait()
{
    int ret = 0;
    int ms = 1000; // 500毫秒
    struct timespec abs_timeout;
    // 设置等待时间为当前时间后的5秒
    // 设置等待时间为当前时间后的指定毫秒数
    clock_gettime(CLOCK_REALTIME, &abs_timeout);
    abs_timeout.tv_sec += ms / 1000;
    abs_timeout.tv_nsec += (ms % 1000) * 1000000;
    if (abs_timeout.tv_nsec >= 1000000000)
    {
        abs_timeout.tv_sec++;
        abs_timeout.tv_nsec -= 1000000000;
    }

    // 等待信号量，最多等待指定毫秒数
    if (sem_timedwait(&controlResult_Sem, &abs_timeout) == -1)
    // if (sem_wait(&controlResult_Sem) == -1)
    {
        perror("sem_timedwait");
        // exit(EXIT_FAILURE);
        return -1; // 没有收到信号量
    }

    return ret;
}

// pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int controlResult_cond_wait()
{
    // pthread_cond_wait(&cond, NULL);
    int ret = 0;
    int ms = 2000; // 500毫秒
    struct timespec abs_timeout;
    // 设置等待时间为当前时间后的5秒
    // 设置等待时间为当前时间后的指定毫秒数
    clock_gettime(CLOCK_REALTIME, &abs_timeout);
    abs_timeout.tv_sec += ms / 1000;
    abs_timeout.tv_nsec += (ms % 1000) * 1000000;
    if (abs_timeout.tv_nsec >= 1000000000)
    {
        abs_timeout.tv_sec++;
        abs_timeout.tv_nsec -= 1000000000;
    }

    // 等待信号量，最多等待指定毫秒数
    pthread_mutex_lock(&mutex);
    if (pthread_cond_timedwait(&cond, &mutex, &abs_timeout) != 0)
    // if (sem_timedwait(&controlResult_Sem, &abs_timeout) == -1)
    // if (sem_wait(&controlResult_Sem) == -1)
    {
        perror("sem_timedwait");
        // exit(EXIT_FAILURE);
        return -1; // 没有收到信号量
    }
    pthread_mutex_unlock(&mutex);
    return 0;
}
int controlResult_Sem_signal()
{
    pthread_cond_signal(&cond);
}
/**
 * @description: 单个设备触发数据上报
 * @param {uint16_t} short_addr 设备短地址
 * @return {*} 返回0正确触发，返回-1上一次的数据上报未完成（数据未返回）
 */
uint8_t OneDevTriggerDataReport(uint16_t short_addr)
{
    uint8_t mask1[13] = {0};
    mask1[0] = 1;

    // if (report_sem_trywait() != 0)
    if (0)
    {
        log_info("上一次数据上报未结束");
        return -1; // 前一次查询未结束，信号量为0
    }
    else // 占用信号量，-1后为0
    {
        FastConbleTriggerDataReport(0, short_addr, mask1); // 立即触发上报
        sem_init(&reportDevState_syncSem, 0, 0);           // 初始化同步的信号量
        reportDevState_syncSem_initialized = true;
        return 0;
    }
}

/**
 * @description: 单个设备上报结果超时等待
 * @return {*}返回0有结果，用队列接收，返回1超时
 */
uint8_t OneDevReportResult_wait()
{
    struct timespec ts;
    int ret = 0;
    clock_gettime(CLOCK_REALTIME, &ts);
    ts.tv_sec += 5; // 设置超时时间为5秒
    if (reportDevState_syncSem_initialized)
    {
        ret = sem_timedwait(&reportDevState_syncSem, &ts);
        sem_destroy(&reportDevState_syncSem);
        reportDevState_syncSem_initialized = false;
    }
    if (ret == -1)
    {
        printf("线程1等待超时\n");
        return 1;
    }
    else
    {
        printf("线程1开始执行\n");
        return 0;
    }
}

void reportMsg_create()
{
    // 创建消息队列的键值
    msg_key = ftok("report_message", 65);
    // 创建消息队列
    msgid = msgget(msg_key, 0666 | IPC_CREAT);
}

uint8_t reportMsg_send(uint8_t *data, uint16_t dataLen)
{
    if (dataLen > MSG_BUFFER_SIZE)
    {
        return -1;
    }
    struct msg_buffer message;
    message.msg_type = 1;
    message.msg_textLen = dataLen;
    memcpy(message.msg_text, data, dataLen);

    msgsnd(msgid, &message, sizeof(struct msg_buffer), 0);
    // reportDevState_syncSem_initialized = true;
    // if (reportDevState_syncSem_initialized)
    // {
    //     // 发送消息
    //     msgsnd(msgid, &message, sizeof(struct msg_buffer), 0);
    //     // 发送同步信号量
    //     sem_post(&reportDevState_syncSem);
    //     uint8_t *p = NULL;
    //     uint16_t dataLen = 0;
    //     reportMsg_nowaitRecv(&p, &dataLen);
    //     log_info("发送队列");
    // }
    // else
    // {
    //     log_info("信号量未初始化");
    // }
}

/**
 * @description: 上报消息无等待接收
 * @param {uint8_t} * 接收的指针，用完后需要free释放
 * @param {uint16_t} dataLen数据长度
 * @return {*}执行结果代码
 */
uint8_t reportMsg_nowaitRecv(uint8_t **data, uint16_t *dataLen)
{
    int ret = 0;
    ret = msgrcv(msgid, &message_recv, sizeof(struct msg_buffer), 1, IPC_NOWAIT);
    // ret = msgrcv(msgid, &message_recv, sizeof(struct msg_buffer), 1, 0);
    if (ret == -1)
    {

        log_info("队列中没有消息可读 %d", errno);
        return -1;
    }
    else
    {
        *data = malloc(message_recv.msg_textLen);
        *dataLen = message_recv.msg_textLen;
        if (*data == NULL)
        {
            log_info("队列分配内存出错");
            return -3;
        }
        else
        {
            log_info("队列接收正常");
            memcpy(*data, message_recv.msg_text, message_recv.msg_textLen);
            return 0;
        }
    }
}